#include "prepare_worker.h"
void PrepareWorker::Execute()
{
  int ret = avformat_open_input(&mPlayer->mFmtCtx, *mUrl, NULL, NULL);
  if (ret < 0)
  {
    SetErrorMessage("cannot open input");
    goto FAIL;
  }
  ret = avformat_find_stream_info(mPlayer->mFmtCtx, NULL);
  if (ret < 0)
  {
    SetErrorMessage("cannot find stream info");
    goto FAIL;
  }
  int nb_streams = mPlayer->mFmtCtx->nb_streams;
  for (int i = 0; i < nb_streams; i++)
  {
    mPlayer->mPar = mPlayer->mFmtCtx->streams[i]->codecpar;
    if (mPlayer->mPar->codec_type == AVMEDIA_TYPE_AUDIO)
    {
      mPlayer->mAudioIdx = i;
      break;
    }
  }
  if (mPlayer->mAudioIdx == -1)
  {
    SetErrorMessage("not contain audio stream");
    goto FAIL;
  }
  mPlayer->mDecoder = avcodec_find_decoder(mPlayer->mPar->codec_id);
  mPlayer->mDecoderCtx = avcodec_alloc_context3(mPlayer->mDecoder);
  ret = avcodec_parameters_to_context(mPlayer->mDecoderCtx, mPlayer->mPar);
  if (ret < 0)
  {
    SetErrorMessage("cannot copy the codecpar to the context");
    goto FAIL;
  }
  ret = avcodec_open2(mPlayer->mDecoderCtx, mPlayer->mDecoder, NULL);
  if (ret < 0)
  {
    SetErrorMessage("cannot open the decoder");
    goto FAIL;
  }
  //44100 2channel float
  mPlayer->mFrame = av_frame_alloc();
  if (mPlayer->mFrame == NULL)
  {
    SetErrorMessage("cannot alloc avframe");
    goto FAIL;
  }
  mPlayer->mPacket = av_packet_alloc();
  if (mPlayer->mPacket == NULL)
  {
    SetErrorMessage("cannot alloc avpacket");
    goto FAIL;
  }
  mPlayer->mSwr = swr_alloc();
  if (mPlayer->mSwr == NULL)
  {
    SetErrorMessage("cannot alloc resampler");
    goto FAIL;
  }
  mPlayer->mSwr = swr_alloc_set_opts(mPlayer->mSwr,
                                     av_get_default_channel_layout(2), AV_SAMPLE_FMT_FLT, 44100,
                                     av_get_default_channel_layout(mPlayer->mPar->channels),
                                     mPlayer->mDecoderCtx->sample_fmt, mPlayer->mDecoderCtx->sample_rate, 0, NULL);
  if (mPlayer->mSwr == NULL)
  {
    SetErrorMessage("cannot set resampler options");
    goto FAIL;
  }
  ret = swr_init(mPlayer->mSwr);
  if (ret < 0)
  {
    SetErrorMessage("cannot init resampler");
    goto FAIL;
  }
 FAIL: mPlayer->mReadyFlag = true;

}

void PrepareWorker::Destroy(){
  mPlayer->UnrefPlayer();
  delete this;
}